package com.gaoxinfu.demo.spring.cloud.jpa.customize.util;

import com.gaoxinfu.demo.spring.cloud.jpa.customize.dto.request.BaseReqDTO;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description: 通过EntityManager 进行jpa 手写sql执行工具类
 * @Author: gaoxinfu
 * @Date: 2021-06-16 15:36
 */
@Component
@Slf4j
public class EntityManagerUtils {

    public final static  String SELECT_MARK ="select";
    public final static  String FROM_MARK ="from";
    public final static String COUNT_MARK=" count(1) ";

    /**
     *
     * @param baseReqDTO
     * @param sql
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> IPagination<T> query(EntityManager entityManager, BaseReqDTO baseReqDTO, String sql, Class<T> clazz) {
        log.info("自定义标签SQL = \n"+ sql );
        // 初始化分页返回体
        IPagination pagination = IPagination.create(baseReqDTO.getPageNo(), baseReqDTO.getPageSize());
        // 查询结果总条数
        BigDecimal total = (BigDecimal) entityManager.createNativeQuery(getTotalNumSql(sql)).getSingleResult();
        pagination.setTotal(total.intValue());
        if (total == new BigDecimal(0)) return pagination;
        Query query = entityManager.createNativeQuery(sql);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        query.setFirstResult(pagination.getOffset()).setMaxResults(pagination.getSize());
        List<Map<String,Object>> resultList = query.getResultList();
        List dataList = new ArrayList();
        if (!CollectionUtils.isEmpty(resultList)){
            resultList.forEach(result ->{
                //result为map对象，key为表的字段，value为表的值
                dataList.add(MapUtil.mapToObject(result,clazz));
            });
        }
        // 列表数据
        pagination.setList(dataList);
        return pagination;
    }

    private static  String getTotalNumSql(String querySql){
        int startIndex = querySql.indexOf(SELECT_MARK);
        if (startIndex<0){
            startIndex = querySql.indexOf(SELECT_MARK.toUpperCase());
        }
        int endIndex = querySql.indexOf(FROM_MARK);
        if (endIndex<0){
            endIndex = querySql.indexOf(FROM_MARK.toUpperCase());
        }
        return  querySql.substring(0,startIndex+SELECT_MARK.length())+COUNT_MARK+querySql.substring(endIndex,querySql.length());
    }
}
